#!/usr/bin/env python3
"""
多方式爬虫工具主程序
提供命令行界面
"""

import argparse
import json
import logging
import sys
from typing import List, Dict, Any
from crawler_manager import CrawlerManager

def setup_logging(level: str = 'INFO'):
    """设置日志"""
    logging.basicConfig(
        level=getattr(logging, level.upper()),
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        handlers=[
            logging.StreamHandler(sys.stdout),
            logging.FileHandler('crawler.log')
        ]
    )

def main():
    parser = argparse.ArgumentParser(description='多方式爬虫工具')
    
    # 基本参数
    parser.add_argument('urls', nargs='*', help='要爬取的URL列表')
    parser.add_argument('-c', '--config', default='config.json', help='配置文件路径')
    parser.add_argument('-m', '--method', choices=['http', 'selenium'], default='http', help='爬取方法')
    parser.add_argument('-o', '--output', help='输出文件名')
    parser.add_argument('-f', '--format', choices=['json', 'csv', 'excel'], default='json', help='输出格式')
    parser.add_argument('-w', '--workers', type=int, default=5, help='并发工作线程数')
    parser.add_argument('--log-level', choices=['DEBUG', 'INFO', 'WARNING', 'ERROR'], default='INFO', help='日志级别')
    
    # 高级参数
    parser.add_argument('--selectors', help='CSS选择器JSON文件路径')
    parser.add_argument('--proxy-file', help='代理文件路径')
    parser.add_argument('--delay', nargs=2, type=float, metavar=('MIN', 'MAX'), help='延时范围（秒）')
    parser.add_argument('--timeout', type=int, default=30, help='请求超时时间')
    parser.add_argument('--retry', type=int, default=3, help='重试次数')
    
    # 分页参数
    parser.add_argument('--pagination', action='store_true', help='启用分页爬取')
    parser.add_argument('--page-param', default='page', help='分页参数名')
    parser.add_argument('--max-pages', type=int, default=10, help='最大页数')
    
    # Selenium参数
    parser.add_argument('--headless', action='store_true', help='Selenium无头模式')
    parser.add_argument('--wait-element', help='等待的元素选择器')
    parser.add_argument('--wait-time', type=int, default=10, help='等待时间')
    
    # 特殊模式
    parser.add_argument('--demo', action='store_true', help='运行演示示例')
    parser.add_argument('--test-proxies', help='测试代理文件中的代理')
    parser.add_argument('--stats', action='store_true', help='显示统计信息')
    
    args = parser.parse_args()
    
    # 设置日志
    setup_logging(args.log_level)
    logger = logging.getLogger(__name__)
    
    if args.demo:
        run_demo()
        return
    
    if args.test_proxies:
        test_proxies(args.test_proxies)
        return
    
    if not args.urls:
        print("错误: 请提供要爬取的URL")
        parser.print_help()
        return
    
    try:
        # 创建爬虫管理器
        crawler = CrawlerManager(args.config)
        
        # 设置代理
        if args.proxy_file:
            crawler.proxy_manager.load_proxies_from_file(args.proxy_file)
            crawler.proxy_manager.test_all_proxies()
            logger.info(f"已加载代理文件: {args.proxy_file}")
        
        # 更新配置
        if args.delay:
            crawler.config.set('request_settings.delay_range', list(args.delay))
        if args.timeout:
            crawler.config.set('request_settings.timeout', args.timeout)
        if args.retry:
            crawler.config.set('request_settings.retry_times', args.retry)
        if args.headless:
            crawler.config.set('selenium_settings.headless', True)
        
        # 加载选择器
        selectors = None
        if args.selectors:
            try:
                with open(args.selectors, 'r', encoding='utf-8') as f:
                    selectors = json.load(f)
                logger.info(f"已加载选择器文件: {args.selectors}")
            except Exception as e:
                logger.error(f"加载选择器文件失败: {e}")
        
        # 构建爬取参数
        crawl_kwargs = {}
        if selectors:
            crawl_kwargs['selectors'] = selectors
        if args.wait_element:
            crawl_kwargs['wait_element'] = args.wait_element
            crawl_kwargs['wait_time'] = args.wait_time
        
        # 执行爬取
        if args.pagination and len(args.urls) == 1:
            # 分页爬取
            logger.info(f"开始分页爬取: {args.urls[0]}")
            results = crawler.crawl_with_pagination(
                base_url=args.urls[0],
                page_param=args.page_param,
                max_pages=args.max_pages,
                method=args.method,
                **crawl_kwargs
            )
        else:
            # 普通爬取
            logger.info(f"开始爬取 {len(args.urls)} 个URL")
            results = crawler.crawl_multiple_urls(
                urls=args.urls,
                method=args.method,
                max_workers=args.workers,
                save_results=False,
                **crawl_kwargs
            )
        
        # 保存结果
        if results:
            filename = args.output or f"crawl_results.{args.format}"
            success = crawler.save_results(results, args.format, filename)
            
            if success:
                logger.info(f"结果已保存到: {filename}")
                print(f"✅ 爬取完成! 成功获取 {len(results)} 个页面")
                print(f"📁 结果文件: {filename}")
            else:
                logger.error("保存结果失败")
        else:
            print("❌ 没有获取到任何结果")
        
        # 显示统计信息
        if args.stats or args.log_level == 'DEBUG':
            stats = crawler.get_statistics()
            print("\n📊 统计信息:")
            print(f"总请求数: {stats['total_requests']}")
            print(f"成功请求数: {stats['successful_requests']}")
            print(f"失败请求数: {stats['failed_requests']}")
            if 'success_rate' in stats:
                print(f"成功率: {stats['success_rate']:.2%}")
            if 'duration_seconds' in stats:
                print(f"总耗时: {stats['duration_seconds']:.2f}秒")
            if 'proxy_stats' in stats:
                proxy_stats = stats['proxy_stats']
                print(f"代理统计: 总数={proxy_stats['total']}, 可用={proxy_stats['working']}, 失败={proxy_stats['failed']}")
        
        crawler.close()
        
    except KeyboardInterrupt:
        print("\n⚠️ 用户中断操作")
    except Exception as e:
        logger.error(f"程序执行出错: {e}")
        print(f"❌ 错误: {e}")

def run_demo():
    """运行演示"""
    print("🕷️ 运行爬虫工具演示...")
    try:
        from examples import main as run_examples
        run_examples()
    except ImportError:
        print("❌ 找不到examples.py文件")

def test_proxies(proxy_file: str):
    """测试代理文件"""
    print(f"🔍 测试代理文件: {proxy_file}")
    
    try:
        from proxy_manager import ProxyManager
        
        proxy_manager = ProxyManager()
        proxy_manager.load_proxies_from_file(proxy_file)
        
        print(f"已加载 {len(proxy_manager.proxies)} 个代理")
        print("正在测试代理可用性...")
        
        proxy_manager.test_all_proxies(max_workers=20)
        
        stats = proxy_manager.get_proxy_stats()
        print(f"✅ 测试完成!")
        print(f"总代理数: {stats['total']}")
        print(f"可用代理: {stats['working']}")
        print(f"失败代理: {stats['failed']}")
        print(f"成功率: {stats['working']/stats['total']*100:.1f}%")
        
        # 保存可用代理
        if stats['working'] > 0:
            output_file = f"working_proxies_{int(time.time())}.txt"
            proxy_manager.save_working_proxies(output_file)
            print(f"📁 可用代理已保存到: {output_file}")
        
    except Exception as e:
        print(f"❌ 测试代理失败: {e}")

if __name__ == "__main__":
    main()